import type { FetchOptions } from 'ofetch'

// RuoYi响应格式
interface RuoYiResponse<T = any> {
  code: number
  msg: string
  data: T
  total?: number
  rows?: T
}

export const useRequest = () => {
  const config = useRuntimeConfig()
  const token = useCookie('Admin-Token')

  // 创建请求实例
  const request = $fetch.create({
    baseURL: '/dev-api',
    onRequest({ options }) {
      // 添加token
      if (token.value) {
        options.headers = {
          ...options.headers as any,
          'Authorization': `Bearer ${token.value}`
        }
      }
    },
    onResponse({ response }) {
      // 处理响应
      const data = response._data as RuoYiResponse

      // 如果是下载文件，直接返回
      if (response.headers.get('content-type')?.includes('application/octet-stream')) {
        return response._data
      }

      // 处理业务错误
      if (data.code !== 200) {
        // 401 未授权
        if (data.code === 401) {
          token.value = null
          navigateTo('/login')
        }
        throw new Error(data.msg || '请求失败')
      }

      // 返回数据
      response._data = data.data || data
    },
    onResponseError({ response }) {
      // 处理HTTP错误
      if (response.status === 401) {
        token.value = null
        navigateTo('/login')
      } else if (response.status === 403) {
        throw new Error('没有权限访问')
      } else if (response.status === 404) {
        throw new Error('请求的资源不存在')
      } else if (response.status >= 500) {
        throw new Error('服务器错误')
      }
    }
  })

  return request
}

// 通用请求方法
export const $api = {
  get: <T = any>(url: string, params?: any, options?: FetchOptions) => {
    return useRequest()(url, {
      method: 'GET',
      params,
      ...options
    }) as Promise<T>
  },

  post: <T = any>(url: string, body?: any, options?: FetchOptions) => {
    return useRequest()(url, {
      method: 'POST',
      body,
      ...options
    }) as Promise<T>
  },

  put: <T = any>(url: string, body?: any, options?: FetchOptions) => {
    return useRequest()(url, {
      method: 'PUT',
      body,
      ...options
    }) as Promise<T>
  },

  delete: <T = any>(url: string, options?: FetchOptions) => {
    return useRequest()(url, {
      method: 'DELETE',
      ...options
    }) as Promise<T>
  }
}